package com.yzion.baselib.activity

import android.content.Context
import android.graphics.Color
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
import androidx.annotation.LayoutRes
import androidx.viewbinding.ViewBinding
import com.blankj.utilcode.util.BarUtils
import com.blankj.utilcode.util.BusUtils
import com.blankj.utilcode.util.KeyboardUtils
import com.blankj.utilcode.util.ThreadUtils
import com.yzion.baselib.R
import com.yzion.baselib.app.BaseApp
import com.yzion.baselib.dialog.BaseLoadingDialog
import com.yzion.baselib.app.IAppProvider
import com.yzion.baselib.view.BaseTitleBar
import me.yokeyword.fragmentation.swipeback.SwipeBackActivity

/**
 * 支持手势侧滑关闭，支持默认标题栏，支持自定义标题栏，支持加载等待弹窗，支持 Toast，支持状态栏浸沉
 * 1.支持开启沉浸式效果 isEnableImmersive 默认是不开启，如果开启沉浸式，布局会自动适应，留出状态栏高度
 * 2.支持自带默认标题栏 isUseDefaultTitleBar 默认是不使用，所以默认情况下是不会加载标题栏的布局文件
 * 3.支持开启侧滑退出 isSwipeBackEnable 默认是不开启，setSwipeBackEnable 可设置侧滑开关
 * 4.如果使用默认标题栏，可以通过 getTitleBar<T> 获取具体实例，T 为 BaseApp 中 createTitleBarView 的类型，
 * 默认实现是 DefaultTitleBar
 * ZJJ
 */
abstract class BaseActivity : SwipeBackActivity(), IBarOption {

    lateinit var context: Context

    //这个是全局默认的标题栏，一般在项目中具有通用性
    private var titleBar: BaseTitleBar? = null

    //在默认标题栏不能满足的情况下使用，一般来说是由于和默认标题栏的UI不一样，需要重新布局而使用自定义
    private var customTitleBar: View? = null

    //通用加载弹窗
    private var defaultLoadingDialog: BaseLoadingDialog? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        context = this
        fragmentAnimator = (applicationContext as IAppProvider).createFragmentAnimator()
        initIntent()

        if (isEnableImmersive()) { //设置沉浸模式
            BarUtils.setStatusBarColor(this, Color.TRANSPARENT)
        }

        setSwipeBackEnable(isSwipeBackEnable())
        if (isTitleBarFlow()) {
            //标题栏覆盖在内容视图之上
            setContentView(R.layout.by_activity_flow)
        } else {
            //标题栏内容视图正常的上下关系
            setContentView(R.layout.by_activity)
        }
        val container = findViewById<FrameLayout>(R.id.base_container)
        val contentView: View?
        val params = FrameLayout.LayoutParams(
            FrameLayout.LayoutParams.MATCH_PARENT,
            FrameLayout.LayoutParams.MATCH_PARENT
        )
        if (getLayoutId() != 0) {
            contentView = layoutInflater.inflate(getLayoutId(), null)
            container.addView(contentView, params)
        } else {
            contentView = initViewBinding(layoutInflater)?.root
            container.addView(contentView, params)
        }

        initTitleBar()
        initView()
        initData()

        //事件总线注册，默认注册
        BusUtils.register(this)
    }

    /**
     * 初始化Intent
     */
    open fun initIntent(){}

    /**
     * 用于使用 ViewBinding 的子类，请查看 BaseBindingActivity
     */
    open fun initViewBinding(inflater: LayoutInflater): ViewBinding? {
        return null
    }

    private fun initTitleBar() {
        defaultLoadingDialog =
            (applicationContext as IAppProvider).createLoadingDialog(context) as BaseLoadingDialog
        val layout = findViewById<ViewGroup>(R.id.base_toolbar_layout)
        val params = ViewGroup.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.WRAP_CONTENT
        )
        customTitleBar = createCustomTitleBar()
        if (customTitleBar != null) { //使用自定义标题栏布局
            layout.addView(customTitleBar, params)
            setStatusBarPadding(layout)
        } else if (isUseDefaultTitleBar()) { //使用默认标题栏布局
            titleBar = createDefaultTitleBar()
            layout.addView(titleBar, params)
            setStatusBarPadding(layout)
            titleBar?.setBarLayout(layout)
        }
    }

    /**
     * 默认样式的加载弹窗，可以通过复写 BaseApp 中的 createLoadingDialog 来自定义样式，具体参见源码
     */
    fun showLoading(text: String?): BaseLoadingDialog? {
        ThreadUtils.runOnUiThread {
            defaultLoadingDialog?.setLoadingTip(text)?.show()
        }
        return defaultLoadingDialog
    }

    /**
     * 隐藏加载中弹窗
     */
    fun hideLoading() {
        defaultLoadingDialog?.dismiss()
    }

    private fun setStatusBarPadding(layout: ViewGroup) {
        if (isEnableImmersive()) {
            //开启沉浸式才需要留出状态栏的高度
            layout.setPadding(0, BarUtils.getStatusBarHeight(), 0, 0)
        }
    }

    override fun createDefaultTitleBar(): BaseTitleBar {
        return (applicationContext as IAppProvider).createTitleBarView(context)
    }

    /**
     * 设置状态栏的字体颜色，一般只有2种，白底黑字，黑底白字
     *
     * @param isBlack if true, set icons and text color to black.
     * if false, set icons and text color to white.
     */
    fun setStatusBarLightMode(isBlack: Boolean) {
        BarUtils.setStatusBarLightMode(window, isBlack)
    }

    /**
     * 获取布局id
     *
     * @return
     */
    @LayoutRes
    protected abstract fun getLayoutId(): Int

    /**
     * 初始化UI
     */
    protected abstract fun initView()

    /**
     * 初始化数据
     */
    abstract fun initData()

    override fun onDestroy() {
        super.onDestroy()
        hideSoftInput()
        hideLoading()
        // 取消事件通知，放在基类，确保每次都有取消。
        BusUtils.unregister(this)
    }

    override fun onBackPressedSupport() {
        super.onBackPressedSupport()
    }

    /**
     * 标题栏是否浮在内容视图之上，默认是false的
     *
     * @return
     */
    override fun isTitleBarFlow(): Boolean {
        return false
    }

    /**
     * 是否开启沉浸式状态栏
     *
     * @return
     */
    open fun isEnableImmersive(): Boolean {
        return false
    }

    /**
     * 如果使用自定义标题栏，即使isUseDefaultTitleBar设置true，
     * 自定义标题栏也会覆盖默认标题栏，自定义标题栏优先
     *
     * @return
     */
    override fun createCustomTitleBar(): View? {
        return null
    }

    /**
     * 是否使用全局配置的TitleBar视图，默认配置是使用DefaultTitleBar
     *
     * @return
     */
    override fun isUseDefaultTitleBar(): Boolean {
        return false
    }

    /**
     * 返回标题栏视图，默认的配置是使用DefaultTitleBar，如果需要自定义请参见DefaultTitleBar注释
     * @return
     */
    override fun <TitleBar : View> getTitleBar(): TitleBar? {
        if (titleBar != null) {
            return titleBar as TitleBar
        }
        return null
    }

    /**
     * 返回自定义标题栏视图，非全局自定义，是当前Fragment的自定义标题栏视图
     * @return
     */
    override fun getCustomTitleBar(): View? {
        return customTitleBar
    }

    /**
     * 是否开启侧滑退出，默认关闭手势侧滑
     */
    fun isSwipeBackEnable(): Boolean {
        return false
    }

    /**
     * 隐藏键盘
     */
    fun hideSoftInput() {
        KeyboardUtils.hideSoftInput(this)
    }
}